package ge.telasi.tasks.ui.task;

import ge.telasi.tasks.model.Task;
import ge.telasi.tasks.model.TaskList;
import ge.telasi.tasks.model.TaskReceiverIndex;
import ge.telasi.tasks.search.Condition;
import ge.telasi.tasks.ui.Platform;
import ge.telasi.tasks.ui.comp.PageableTable;
import ge.telasi.tasks.ui.comp.TableModel;
import ge.telasi.tasks.ui.UIUtils;
import ge.telasi.tasks.ui.log.LoggerUtils;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import javax.swing.Icon;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;

/**
 * @author dimitri
 */
public class TaskIndexTable extends PageableTable<TaskReceiverIndex> {
    private static final long serialVersionUID = 7098528219573079543L;
    private List<Condition> conditions;

    public TaskIndexTable() {
        super();
        setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        TableColumnModel colModel = getColumnModel();
        TableColumn colStatus = colModel.getColumn(TaskTable.STATUS);
        TableColumn colAttachment = colModel.getColumn(TaskTable.ATTACHMENT);
        colStatus.setResizable(false);
        colAttachment.setResizable(false);
        for (int i = 0; i < getColumnCount(); i++) {
            getColumnModel().getColumn(i).setCellRenderer(new TaskRenderer());
        }
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent evnt) {
                if (evnt.getClickCount() > 1) {
                    openTask();
                }
            }
        });
    }

    public void printSelection() {
        TaskReceiverIndex index = getSelection();
        if (index != null) {
            try {
                Task task = index.getTask();
                Platform pl = Platform.getDefault();
                byte[] data = pl.getFacade().getTaskReport(pl.getCredentials(), task);
                pl.writeAndOpenTempFile("taskreport.pdf", data);
            } catch (Exception ex) {
                LoggerUtils.manageException(this, ex);
            }
        }
    }

    @Override
    protected TableModel<TaskReceiverIndex> createEmptyModel() {
        return new TaskModel();
    }

    @Override
    protected List<TaskReceiverIndex> getDataFromServer(Platform pl) throws Exception {
        int page = getPage();
        int perPage = getPerPage();
        TaskList tasks = pl.getFacade().findTasks(pl.getCredentials(), page, perPage, conditions);
        setTotalCount(tasks.getTotalCount());
        return tasks;
    }

    public List<Condition> getConditions() {
        return conditions;
    }

    public void setConditions(List<Condition> conditions) {
        this.conditions = conditions;
    }

    public void deleteTask() {
        TaskReceiverIndex selected = getSelection();
        Platform pl = Platform.getDefault();
        if (selected != null && pl.validateConnection()) {
            String msg = pl.getLocaleManager().getMessage("General.deleteMsg", selected.getTask().getNumber());
            if (UIUtils.askConfirmation(this, msg)) {
                try {
                    pl.getFacade().deleteTask(pl.getCredentials(), selected.getTask());
                    remove(selected);
                } catch (Exception ex) {
                    LoggerUtils.manageException(this, ex);
                }
            }
        }
    }

    public void openNew() {
        if (Platform.getDefault().validateConnection()) {
            NewTaskDialog dialog = new NewTaskDialog(this);
            UIUtils.openDialog(dialog);
            if (dialog.isApproved()) {
                refresh();
            }
        }
    }

    public void openTask() {
        TaskReceiverIndex selected = getSelection();
        if (selected != null && Platform.getDefault().validateConnection()) {
            if (selected.getTask().getTaskStatus() == Task.STATUS_DRAFT) {
                openDraftTask(selected);
            } else {
                openNonDraftTask(selected);
            }
            selected.setNew(false);
        }
    }

    private void openDraftTask(final TaskReceiverIndex taskIndex) {
        Platform pl = Platform.getDefault();
        try {
            Task task = pl.getFacade().getTask(pl.getCredentials(), taskIndex.getTask());
            NewTaskDialog dialog = new NewTaskDialog(this);
            dialog.setTask(task);
            dialog.addPropertyChangeListener(new PropertyChangeListener() {
                public void propertyChange(PropertyChangeEvent evt) {
                    if ("task".equals(evt.getPropertyName())) {
                        Task task = (Task) evt.getNewValue();
                        taskIndex.setNew(false);
                        taskIndex.setTask(task);
                        replace(taskIndex);
                    }
                }
            });
            UIUtils.openDialog(dialog);
            if (dialog.isApproved()) {
                refresh();
            }
        } catch (Exception ex) {
            LoggerUtils.manageException(this, ex);
        }
    }

    private void openNonDraftTask(final TaskReceiverIndex taskIndex) {
        Platform pl = Platform.getDefault();
        try {
            Task task = pl.getFacade().getTask(pl.getCredentials(), taskIndex.getTask());
            TaskEditDialog dialog = new TaskEditDialog(this);
            dialog.addPropertyChangeListener(new PropertyChangeListener() {
                public void propertyChange(PropertyChangeEvent evt) {
                    if ("task".equals(evt.getPropertyName())) {
                        Task task = (Task) evt.getNewValue();
                        taskIndex.setNew(false);
                        taskIndex.setTask(task);
                        replace(taskIndex);
                    }
                }
            });
            dialog.setTask(task);
            UIUtils.openDialog(dialog);
        } catch (Exception ex) {
            LoggerUtils.manageException(this, ex);
        }
    }

    @Override
    protected String getPreferenceName() {
        return "8945633156633221144556";
    }

    @Override
    protected int[] getDefaultColumnWidthes() {
        return new TaskTable().getDefaultColumnWidthes();
    }

    class TaskModel extends TableModel<TaskReceiverIndex> {
        TaskTable.TaskTableModel taskModel = new TaskTable.TaskTableModel();

        @Override
        public int getColumnCount() {
            return taskModel.getColumnCount();
        }

        @Override
        public Class<?> getColumnClass(int columnIndex) {
            return taskModel.getColumnClass(columnIndex);
        }

        @Override
        public String getColumnName(int column) {
            return taskModel.getColumnName(column);
        }

        @Override
        public boolean isCellEditable(int row, int column) {
            return taskModel.isCellEditable(row, column);
        }

        @Override
        public Object getValueAt(int row, int column) {
            TaskReceiverIndex taskIndex = getObjectAt(row);
            Task task = taskIndex.getTask();
            return taskModel.getValue(task, column);
        }

    }

    class TaskRenderer extends DefaultTableCellRenderer {
        private static final long serialVersionUID = -8576935176402091643L;
        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            TaskModel model = (TaskModel) table.getModel();
            TaskReceiverIndex index = model.getObjectAt(row);
            if (index.isNew()) {
                setFont(UIUtils.makeBold(getFont()));
            }
            if (value instanceof Icon) {
                setText("");
                setIcon((Icon) value);
            }
            if (value == null) {
                setText(null);
                setIcon(null);
            }
            return this;
        }
    }

}
